<template>
  <div class="yg_catalog" v-if="catalog && catalog?.length > 0">
    <h3 class="title">目录</h3>
    <ul class="list">
      <li
        v-for="item in catalog"
        :key="item?.id"
        :class="{ item: true, active: item.read === true }"
        :style="{ paddingLeft: `${item.level * 12}px` }"
        @click="anchorJump(item?.id)"
      >
        {{ item.title }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "ygCatalog",
  props: {
    id: {
      type: String,
      default: "",
    },
    list: {
      type: Array,
      default: () => {
        return [];
      },
    },
  },
  data() {
    return {
      catalog: null,
    };
  },
  watch: {
    id: {
      handler() {
        window.addEventListener("scroll", this.getReading);
      },
      immediate: true,
    },
    list: {
      handler() {
        this.catalog = this.list;
      },
      immediate: true,
    },
  },
  methods: {
    getReading() {
      //获取页面滚动值
      let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
      let clientHeight =
        window.innerHeight || document.documentElement.clientHeight;
      //遍历小标题
      for (let i = 0; i < this.catalog.length; i++) {
        //获取小标题距离屏幕顶端的距离
        let offsetTop = document.querySelector(
          "#" + this.catalog[i].id
        ).offsetTop;
        //根据条件做出判断，当小标题和屏幕顶端的距离小于屏幕高度一半且没有被标明在读时，就将其背景颜色改变。
        if (
          offsetTop - scrollTop < clientHeight / 2 &&
          offsetTop - scrollTop > 0 &&
          this.catalog[i].read == false
        ) {
          this.catalog[i].read = true;
          //再将其他小标题背景色改成未读的背景色
          for (let j = 0; j < this.catalog.length; j++) {
            if (j != i) {
              this.catalog[j].read = false;
            }
          }
        }
      }
    },
    anchorJump(id) {
      document.querySelector(`#${id}`).scrollIntoView({
        behavior: "smooth",
        // 定义动画过渡效果， "auto"或 "smooth" 之一。默认为 "auto"
        block: "center",
        // 定义垂直方向的对齐， "start", "center", "end", 或 "nearest"之一。默认为 "start"
        inline: "nearest",
        // 定义水平方向的对齐， "start", "center", "end", 或 "nearest"之一。默认为 "nearest"
      });
    },
  },
  destroyed() {
    window.removeEventListener("scroll", this.getReading);
  },
};
</script>

<style lang="scss" scoped>
.yg_catalog {
  position: sticky;
  top: 60px;
  display: flex;
  flex-direction: column;
  border-radius: 4px;
  overflow: hidden;
  & > .title {
    display: flex;
    flex-direction: row;
    align-items: center;
    margin: 0;
    padding: 0 12px;
    height: 40px;
    background-color: #eaeaea;
    font-size: 14px;
    font-weight: 500;
    color: #3d3d3d;
    user-select: none;
    cursor: default;
  }
  & > .list {
    display: flex;
    flex-direction: column;
    padding: 4px 0 !important;
    background-color: #fff;
    & > .item {
      padding: 8px 0;
      font-size: 14px;
      font-weight: 400;
      color: #171717;
      line-height: 14px;
      user-select: none;
      &:hover {
        background-color: rgb(254, 242, 235);
      }
      &.active {
        background-color: rgb(254, 242, 235);
      }
    }
  }
}
</style>
